import System
import System.IO
import System.Diagnostics
import System.Configuration

class Bug:
            lastRun ={}
            notifier as Notifier
            sourcePath as string
            unittestFinder as duck
            NUnitPath = ConfigurationManager.AppSettings["NUnitPath"]

            def constructor(folder as string, fileFinder as duck):
                         unittestFinder = fileFinder
                         sourcePath = folder
                         notifier = Notifier()
                         notifier.Notify("Starting", "Watching: " + sourcePath)
                         unittestFinder.FindTests(sourcePath)

            def StartWatching():
                         watcher = FileSystemWatcher(sourcePath, Filter: "*.dll")
                         watcher.IncludeSubdirectories = true
                         watcher.Changed += def(source, e as FileSystemEventArgs):
                                     print "${e.Name} has changed ${DateTime.Now}"
                                     utah = UnittestAssemblyHelper(e.Name)
                                     if(utah.IsUnittest()):
                                                  unittestName = sourcePath + e.Name
                                                  testFileName = FileInfo(unittestName).Name
                                                  RunUnittestsAndNotify(unittestName, testFileName)
                                     elif(unittestFinder.HasUnittest(FileInfo(e.FullPath))):
                                                  unittestName =  unittestFinder.GetUnittest(FileInfo(e.Name))
                                                  testFileName = FileInfo(unittestName).Name
                                                  RunUnittestsAndNotify(unittestName, testFileName)
                                                  
                         watcher.EnableRaisingEvents = true;
                         print "Watching..."

            def RunUnittestsAndNotify(unittestName as string, testFileName as string):
            	if(not HasRunLast10Seconds(testFileName)):

                                                              unittestRunResult = Execute(NUnitPath , unittestName + " /nologo")
                                                              lastRun[testFileName] = DateTime.Now
                                                              print unittestRunResult
                                                              if(unittestRunResult.Contains("Failures: 0") and unittestRunResult.Contains("Errors: 0")):
                                                                           notifier.Notify("Unittest run" , "Sucess!:\n " + testFileName)
                                                              else:
                                                                           notifier.NotifyFailure("Unittest run", "Failure!:\n " + testFileName)
                                                  print ""
            	
            def Execute(program as string, params as string)as string:
                                     psi = ProcessStartInfo (program, params)
                                     psi.UseShellExecute = false
                                     psi.RedirectStandardOutput = true
                                     process = Process.Start(psi)
                                     output = process.StandardOutput.ReadToEnd()
                                     return output

            def HasRunLast10Seconds(name as string) as bool:
                         if(lastRun[name] == null):
                                     return false

                         lastRunDate = cast(DateTime, lastRun[name])
                         if(lastRunDate < DateTime.Now.AddSeconds(-10)):
                                     return false
                         return true


sourcePath = ConfigurationManager.AppSettings["SourcePath"] 
unittestFinderStrategy = ConfigurationManager.AppSettings["UnittestFinderStrategy"] 

ff as duck

if(unittestFinderStrategy == "SingleUnittestFileFinder"):
	ff = SingleUnittestFileFinder("CodeRushTest.Tests.dll")
else:
	ff= FileFinder()
                       
Bug(sourcePath, ff).StartWatching.BeginInvoke()
Console.Read()